/* -------------------------------------------------------------------------- *
   TestWinUnit - Maria Blees (maria.blees@microsoft.com)
 * -------------------------------------------------------------------------- */
#include "TempFile.h"
#include "WinUnit.h"
#include "MockLogger.h"
#include "FileEnumerator.h"

#include <io.h>

using namespace WinUnitLib;

TempFile::TempFile()
{
    // From docs for GetTempFile
    const int maxPathLength = MAX_PATH - 14;
    wchar_t tempDir[maxPathLength] = L"";

    DWORD size = GetTempPathW(maxPathLength, tempDir);
    WIN_ASSERT_WINAPI_SUCCESS(size != 0, _T("GetTempPathW failed."));
    WIN_ASSERT_TRUE(size <= maxPathLength, _T("Result of GetTempPathW was too long."));

    WIN_ASSERT_WINAPI_SUCCESS(0 != GetTempFileNameW(tempDir, L"WUT", 0, _fullFileName));
    CreateTempFile();
}

TempFile::TempFile(const wchar_t* directoryName, const wchar_t* fileName)
{
    DWORD attributes = ::GetFileAttributesW(directoryName);
    WIN_ASSERT_WINAPI_SUCCESS(INVALID_FILE_ATTRIBUTES != attributes);
    WIN_ASSERT_TRUE((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);

    // Start with the directory name.
    wcscpy_s(_fullFileName, directoryName);

    // Append trailing backslash if none.
    size_t directoryNameLength = ::wcslen(_fullFileName);
    if (_fullFileName[directoryNameLength - 1] != L'\\')
    {
        ::wcscat_s(_fullFileName, L"\\"); // Ensures null terminator
    }

    // Now add the file name.
    ::wcscat_s(_fullFileName, fileName);

    CreateTempFile();
}

void TempFile::CreateTempFile()
{
    SECURITY_ATTRIBUTES sa = {
        sizeof(SECURITY_ATTRIBUTES),
        NULL,       
        TRUE        // inheritable
    };
    // Create the temporary file--we'll leave it open until we're
    // done with it.
    _handle = CreateFileW(
        _fullFileName, 
        GENERIC_WRITE,      // desired access 
        FILE_SHARE_READ,    // share mode
        &sa,                // lpSecurityAttributes
        CREATE_ALWAYS,      
        FILE_ATTRIBUTE_NORMAL, 
        NULL);

    WIN_ASSERT_WINAPI_SUCCESS(INVALID_HANDLE_VALUE != _handle, _T("CreateFile failed."));
}

TempFile::~TempFile()
{
    if (_handle != INVALID_HANDLE_VALUE)
    {
        BOOL fileClosed = ::CloseHandle(_handle);
        if (!fileClosed)
        {
            WIN_TRACE(__TFUNCTION__ _T(": CloseHandle failed\n"));
        }
        BOOL fileDeleted = ::DeleteFileW(_fullFileName);
        if (!fileDeleted)
        {
            WIN_TRACE(__TFUNCTION__ _T(": DeleteFileW failed\n"));
        }
    }
}

TempFile::operator HANDLE()
{
    return _handle;
}

const wchar_t* TempFile::GetName() const
{
    return _fullFileName;
}

